package models;

public class ProfilConsommation {
	
	static final int N = 8760;
	
	static final Double TARIF_NORMAL = 0.1440;
	static final Double TARIF_HEURE_PLEINE = 0.1572;
	static final Double TARIF_HEURE_CREUSE = 0.1096;
	
	static final Double TARIF_REVENTE_PV = 0.3136;
	static final Double TARIF_REVENTE_EOLIENNE = 0.082;
	
	private Courbe _courbeDeCharge;
	
	public Double factureSansRenouvelable_tarif_HP_HC() {
		Double facture = 0.0;
		
		for (int j = 0; j < 365; j++) {
			for (int h = 0; h < 365; h++) {
				if (h < 6 || h >= 22) {
					facture += _courbeDeCharge.getPoint(j * 24 + h) * TARIF_HEURE_CREUSE;
				}
				else {
					facture += _courbeDeCharge.getPoint(j * 24 + h) * TARIF_HEURE_PLEINE;
				}				
			}
		}
		
		return facture;
	}
	
	public Double factureSansRenouvelable_tarif_Base() {
		Double facture = 0.0;

		for (int j = 0; j < 365; j++) {
			for (int h = 0; h < 365; h++) {
				facture += _courbeDeCharge.getPoint(j * 24 + h) * TARIF_NORMAL;
			}
		}
		
		return facture;
	}
	
	public Courbe diffConsommationProduction (Courbe productionRenouvelable) {
		return _courbeDeCharge.add(productionRenouvelable.multiple(-1.0));
	}
	
	public Double factureAvecRenouvelable_tarif_HP_HC(String choixRenouvelable, Courbe productionRenouvelable) {
		Double tarifReventeRenouvelable = 0.0;
		
		if (choixRenouvelable.equals("pv")) {
			tarifReventeRenouvelable = TARIF_REVENTE_PV;
		}
		else if (choixRenouvelable.equals("eolienne")) {
			tarifReventeRenouvelable = TARIF_REVENTE_EOLIENNE;
		}
		
		Double facture = 0.0;
		Courbe coubreDiffConsommationProduction = diffConsommationProduction(productionRenouvelable);
		
		for (int j = 0; j < 365; j++) {
			for (int h = 0; h < 365; h++) {
			    // Diff > 0 => on doit des sous à EDF
				if (coubreDiffConsommationProduction.getPoint(j * 24 + h) <= 0) {
					if (h < 6 || h >= 22) {
						facture += coubreDiffConsommationProduction.getPoint(j * 24 + h) * TARIF_HEURE_CREUSE;
					}
					else {
						facture += coubreDiffConsommationProduction.getPoint(j * 24 + h) * TARIF_HEURE_PLEINE;
					}
				}
				// Diff < 0 => on peut revendre à EDF
				else {
					facture -= coubreDiffConsommationProduction.getPoint(j * 24 + h) * tarifReventeRenouvelable;
				}
			}
		}
		
		return facture;
	}
	
	public Double factureAvecRenouvelable_tarif_Base(String choixRenouvelable, Courbe productionRenouvelable) {
		Double tarifReventeRenouvelable = 0.0;
		
		if (choixRenouvelable.equals("pv")) {
			tarifReventeRenouvelable = TARIF_REVENTE_PV;
		}
		else if (choixRenouvelable.equals("eolienne")) {
			tarifReventeRenouvelable = TARIF_REVENTE_EOLIENNE;
		}
		
		Double facture = 0.0;
		Courbe coubreDiffConsommationProduction = diffConsommationProduction(productionRenouvelable);
		
		for (int j = 0; j < 365; j++) {
			for (int h = 0; h < 365; h++) {
			    // Diff > 0 => on doit des sous à EDF
				if (coubreDiffConsommationProduction.getPoint(j * 24 + h) <= 0) {
					facture += coubreDiffConsommationProduction.getPoint(j * 24 + h) * TARIF_NORMAL;
				}
				// Diff < 0 => on peut revendre à EDF
				else {
					facture -= coubreDiffConsommationProduction.getPoint(j * 24 + h) * tarifReventeRenouvelable;
				}
			}
		}
		
		return facture;
	}
	
	private Double dureeRemboursement_tarif_HP_HC(String choixRenouvelable, Double prixImplementation, Courbe productionRenouvelable){
		Double facSansRenouvelable_tarif_HP_HC = factureSansRenouvelable_tarif_HP_HC();
		Double facAvecRenouvelable_tarif_HP_HC = factureAvecRenouvelable_tarif_HP_HC(choixRenouvelable, productionRenouvelable);		
		Double economieRealisee_tarif_HP_HC = facSansRenouvelable_tarif_HP_HC - facAvecRenouvelable_tarif_HP_HC;
		
		return (prixImplementation / economieRealisee_tarif_HP_HC);
	}
	
	private Double dureeRemboursement_tarif_Base(String choixRenouvelable, Double prixImplementation, Courbe productionRenouvelable){
		Double facSansRenouvelable_tarif_Base = factureSansRenouvelable_tarif_Base();
		Double facAvecRenouvelable_tarif_Base = factureAvecRenouvelable_tarif_Base(choixRenouvelable, productionRenouvelable);		
		Double economieRealisee_tarif_Base = facSansRenouvelable_tarif_Base - facAvecRenouvelable_tarif_Base;
		
		return (prixImplementation / economieRealisee_tarif_Base);
	}
	
	private Double prixImplementation (String choixRenouvelable, Double prixUnitaire, int nombre) {
		Double prixImplementation = prixUnitaire*nombre;
		
		if (choixRenouvelable.equals("pv")) {
			prixImplementation *= 1.8;
		}
		
		return prixImplementation;
	}
	
	public Double dureeRemboursement (String choixRenouvelable, Double prixUnitaire, int nombre, Courbe productionRenouvelable) {
		Double prixImplementation = prixImplementation (choixRenouvelable, prixUnitaire, nombre);
		Double dureeRemboursement_tarif_HP_HC = dureeRemboursement_tarif_HP_HC(choixRenouvelable, prixImplementation, productionRenouvelable);
		Double dureeRemboursement_tarif_Base = dureeRemboursement_tarif_Base(choixRenouvelable, prixImplementation, productionRenouvelable);

		return Math.min(dureeRemboursement_tarif_HP_HC, dureeRemboursement_tarif_Base);
	}
	
	public String optionTarifaire(String choixRenouvelable, Double prixUnitaire, int nombre, Courbe productionRenouvelable) {
		String optionTarifaire;
		Double prixImplementation = prixImplementation (choixRenouvelable, prixUnitaire, nombre);
		Double dureeRemboursement_tarif_HP_HC = dureeRemboursement_tarif_HP_HC(choixRenouvelable, prixImplementation, productionRenouvelable);
		Double dureeRemboursement_tarif_Base = dureeRemboursement_tarif_Base(choixRenouvelable, prixImplementation, productionRenouvelable);

	    if (dureeRemboursement_tarif_HP_HC < dureeRemboursement_tarif_Base) {
	    	optionTarifaire = "Heure Pleine / Heure Creuse";
	    }
	    else {
	    	optionTarifaire = "Base";
	    }
	    
	    return optionTarifaire;
	}

}
